package lee.vioson.remotedata.manager

import android.content.Context
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.last
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.withContext
import lee.vioson.remotedata.bean.LoginResult

/**
 *Author:viosonlee
 *Date:2023/6/10
 *DESCRIPTION:
 */
enum class UserManager {
    INSTANCE;

    suspend fun init(context: Context) {
        withContext(Dispatchers.IO) {
            getEmailLoginResult(context).launchIn(this)
            getAnonymousLoginResult(context).launchIn(this)
        }
    }

    var anonymousLoginResult: LoginResult? = null
    var emailLoginResult: LoginResult? = null

    suspend fun saveEmailLoginResult(context: Context, loginResult: LoginResult) {
        emailLoginResult = loginResult
        context.dataStore.edit {
            it[key_email_login] = Gson().toJson(loginResult)
        }
    }


    suspend fun saveAnonymousLoginResult(context: Context, loginResult: LoginResult) {
        anonymousLoginResult = loginResult
        context.dataStore.edit {
            it[key_anonymous_login] = Gson().toJson(loginResult)
        }
    }

    fun getEmailLoginResult(context: Context) = flow {
        val json = context.dataStore.data.map { it[key_email_login] }.first()
        val loginResult = if (json.isNullOrEmpty()) {
            null
        } else {
            Gson().fromJson(json, LoginResult::class.java)
        }
        emailLoginResult = loginResult
        emit(loginResult)
    }

    fun getAnonymousLoginResult(context: Context) = flow {
        val json = context.dataStore.data.map { it[key_anonymous_login] }.first()
        val loginResult = if (json.isNullOrEmpty()) {
            null
        } else {
            Gson().fromJson(json, LoginResult::class.java)
        }
        anonymousLoginResult = loginResult
        emit(loginResult)
    }


    fun getLoginResult(context: Context) = when (loginType) {
        LoginType.EMAIL -> getEmailLoginResult(context)
        else -> getAnonymousLoginResult(context)
    }


    /**
     * There is two user level in each login type:vip or normal,define by userInfo.vipType
     */
    val isVip: Boolean
        get() = when (loginType) {
            LoginType.EMAIL -> {
                emailLoginResult?.userInfo?.vipType == 0
            }

            else -> anonymousLoginResult?.userInfo?.vipType == 0
        }

    /**
     * This app doesn't has no-login status,at last anonymous login can enter it
     */
    val loginType: LoginType
        get() = if (emailLoginResult != null) {
            LoginType.EMAIL
        } else {
            LoginType.ANONYMOUS
        }
}

enum class LoginType {
    ANONYMOUS, EMAIL, GOOGLE, FACEBOOK, TWITTER
}